#include "swserverwidget.h"

SWServerWidget::SWServerWidget(int port)
    : SWCommonWidget()
{
    m_server = NULL;

    connectSignals();
    createServer(port);
    setWindowTitle("Server:" + QString::number(port, 10));
}

SWServerWidget::~SWServerWidget()
{
    if (m_server)
        m_server->close();
}

void SWServerWidget::connectSignals()
{
    connect(m_sendLine, SIGNAL(returnPressed()), this, SLOT(sendData()));
    connect(m_outputButton, SIGNAL(clicked()), this, SLOT(sendData()));
}

void SWServerWidget::clientDisconnected()
{
    addEvent("Client Disconnected", "", "");
    m_client = NULL;
    setConnected(false);
}

void SWServerWidget::createServer(int port)
{
    m_client = NULL;
    m_server = new QTcpServer;
    m_server->listen(QHostAddress::Any, port);
    if (m_server->isListening()) {
        addEvent("Server Started", "", "");
        connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
    }
}

void SWServerWidget::newConnection()
{
    if (m_client != NULL) {
        /* Focusing on one client at a time simplifies the code. Also, it's
           assumed that the clients won't be interacting so it wouldn't make
           a difference to allow this.
           But mostly that it simplifies a lot of code. */
        m_server->nextPendingConnection()->close();
        return;
    }

    m_client = m_server->nextPendingConnection();
    addEvent("Client Connected", "", "");
    connect(m_client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
    connect(m_client, SIGNAL(readyRead()), this, SLOT(readyRead()));
    setConnected(true);
}

void SWServerWidget::readyRead()
{
    static char buffer[4096];

    while (1) {
        qint64 lineLen = m_client->readLine(buffer, sizeof(buffer));
        if (lineLen == 0)
            break;

        /* This might contain \0 in it, so use the constructor that specifies a
           size. This is also why no \0 is added to the end. */
        QByteArray data(buffer, lineLen);
        addEvent("Data Received", byteFormat(data), textFormat(data));
    }
}

void SWServerWidget::sendData()
{
    QByteArray data = escapeText(m_sendLine->text());
    if (m_isValidEscape == false) {
        m_statusBar->showMessage(tr("Error: Invalid escape sequence.\n"));
        return;
    }
    else
        m_statusBar->clearMessage();

    if (data.size() == 0)
        return;

    addEvent("Data Sent", byteFormat(data), textFormat(data));
    m_client->write(data);
    m_sendLine->clear();
}
